package com.example.task8v27window;

import java.net.URL;
import java.util.Arrays;
import java.util.ResourceBundle;
import java.util.stream.Collectors;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;

public class HelloController {

    @FXML
    private ResourceBundle resources;

    @FXML
    private URL location;

    @FXML
    private GridPane arrPane;

    @FXML
    private Label resLabel;

    @FXML
    private Button setSizeBtn;

    @FXML
    private Button solveBtn;

    @FXML
    private TextField xTF;

    @FXML
    private TextField yTF;
    private int[][] arr;

    @FXML
    void setSizeClick(ActionEvent event) {
        arrPane.getChildren().clear();
        int x = Integer.parseInt(xTF.getText()), y = Integer.parseInt(yTF.getText());
        this.arr = new int[x][y];
        int i, j;
        for (i = 0; i < y; i++) {
            for (j = 0; j < x; j++) {
                TextField tf = new TextField();
                final int ii = i, jj = j;
                tf.textProperty().addListener((observable, oldvalue, newvalue) -> {
                    newvalue = newvalue == "" ? "0" : newvalue;
                    int t = Integer.parseInt(newvalue);
                    arr[jj][ii] = t;
                });
                arrPane.add(tf, i, j);
            }
        }
    }

    @FXML
    void solveClick(ActionEvent event) {
        int[] flatArray = Arrays.stream(arr)
                .flatMapToInt(Arrays::stream)
                .toArray();

        //Count duplicates
        Object[] duplicates = Arrays.stream(flatArray).boxed()
                // Group all integers together
                .collect(Collectors.groupingBy(i -> i, Collectors.counting()))
                // Keep key/value pairs whose value > 1
                .entrySet()
                .stream()
                .filter(entry -> entry.getValue() > 1)
                .toArray();
        if (duplicates.length > 0)
            resLabel.setText("false");
        else
            resLabel.setText(Boolean.toString(checkLeft(arr, arr[0].length, arr.length) || checkRight(arr, arr[0].length, arr.length)));
    }

    public static boolean checkRight(int[][] arr, int w, int h) {
        int x = 0, y = 0, tx = 0, ty = 0;
        while (x < w - 1 || y < h - 1) {
            if (y < h - 1)
                y++;
            else
                x++;
            if (arr[y][x] <= arr[ty][tx])
                return false;
            tx = x;
            ty = y;
            while (y > 0 && x < w - 1) {
                x++;
                y--;
                if (arr[y][x] <= arr[ty][tx])
                    return false;
                tx = x;
                ty = y;
            }
            if (x < w - 1)
                x++;
            else
                y++;
            if (arr[y][x] <= arr[ty][tx])
                return false;
            while (y < h - 1 && x > 0) {
                x--;
                y++;
                if (arr[y][x] <= arr[ty][tx])
                    return false;
                tx = x;
                ty = y;
            }
        }
        return true;
    }

    public static boolean checkLeft(int[][] arr, int w, int h) {
        int x = 0, y = 0, tx = 0, ty = 0;
        while (x < w - 1 || y < h - 1) {
            if (y < h - 1)
                y++;
            else
                x++;
            if (arr[y][x] >= arr[ty][tx])
                return false;
            tx = x;
            ty = y;
            while (y > 0 && x < w - 1) {
                x++;
                y--;
                if (arr[y][x] >= arr[ty][tx])
                    return false;
                tx = x;
                ty = y;
            }
            if (x < w - 1)
                x++;
            else
                y++;
            if (arr[y][x] >= arr[ty][tx])
                return false;
            while (y < h - 1 && x > 0) {
                x--;
                y++;
                if (arr[y][x] >= arr[ty][tx])
                    return false;
                tx = x;
                ty = y;
            }
        }
        return true;
    }

    @FXML
    void initialize() {
        assert arrPane != null : "fx:id=\"arrPane\" was not injected: check your FXML file 'hello-view.fxml'.";
        assert resLabel != null : "fx:id=\"resLabel\" was not injected: check your FXML file 'hello-view.fxml'.";
        assert setSizeBtn != null : "fx:id=\"setSizeBtn\" was not injected: check your FXML file 'hello-view.fxml'.";
        assert solveBtn != null : "fx:id=\"solveBtn\" was not injected: check your FXML file 'hello-view.fxml'.";
        assert xTF != null : "fx:id=\"xTF\" was not injected: check your FXML file 'hello-view.fxml'.";
        assert yTF != null : "fx:id=\"yTF\" was not injected: check your FXML file 'hello-view.fxml'.";

    }

}
